package com.dlc.shop.manager.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dlc.shop.bean.bo.AllinpaySettlementBO;
import com.dlc.shop.bean.bo.OrderChangeShopWalletAmountBO;
import com.dlc.shop.bean.enums.PayEntry;
import com.dlc.shop.bean.enums.PayStatus;
import com.dlc.shop.bean.enums.ShopWalletChangeReason;
import com.dlc.shop.bean.event.GetDistributionUserIncomeEvent;
import com.dlc.shop.bean.model.OrderSettlement;
import com.dlc.shop.bean.model.PayInfo;
import com.dlc.shop.bean.model.RefundInfo;
import com.dlc.shop.bean.model.ShopWalletLog;
import com.dlc.shop.bean.vo.allinpay.SplitRuleVO;
import com.dlc.shop.common.allinpay.constant.AllinpayConstant;
import com.dlc.shop.common.allinpay.order.req.AgentPay;
import com.dlc.shop.common.allinpay.order.req.BatchAgentPay;
import com.dlc.shop.common.allinpay.order.req.SplitRule;
import com.dlc.shop.common.bean.Allinpay;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.enums.PayType;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ResponseEnum;
import com.dlc.shop.common.util.Arith;
import com.dlc.shop.common.util.BeanUtil;
import com.dlc.shop.config.ShopConfig;
import com.dlc.shop.dao.OrderSettlementMapper;
import com.dlc.shop.dao.PayInfoMapper;
import com.dlc.shop.dao.RefundInfoMapper;
import com.dlc.shop.dao.ShopWalletLogMapper;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.SysConfigService;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 统一支付工具
 *
 * @author FrozenWatermelon
 */
@Service
@AllArgsConstructor
public class AllinpayOrderManager {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final AllinpayManager allinpayManager;
    private final PayInfoMapper payInfoMapper;
    private final RefundInfoMapper refundInfoMapper;
    private final SysConfigService sysConfigService;
    private final SegmentService segmentService;
    private final ShopConfig shopConfig;
    private final OrderSettlementMapper orderSettlementMapper;
    private final ShopWalletLogMapper shopWalletLogMapper;
    private final ApplicationContext applicationContext;

    /**
     * 通联结算
     * @param orderChangeShopWalletAmountBO
     */
    public void doAllinPaySettlement(OrderChangeShopWalletAmountBO orderChangeShopWalletAmountBO) {
        Integer payEntry = PayEntry.ORDER_SETTLEMENT.value();
        String orderNumber = orderChangeShopWalletAmountBO.getOrderNumber();
        // 找出当时支付的payId
        OrderSettlement orderSettlement = orderSettlementMapper.selectOne(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getOrderNumber, orderNumber).eq(OrderSettlement::getPayStatus, 1));
        // 获取商家，分销员的收入明细
        AllinpaySettlementBO allinpaySettlementBO = getShopWaitSettlementAmount(orderChangeShopWalletAmountBO, orderSettlement.getPayNo());
        PayInfo settlementPayInfo = payInfoMapper.getByOrderIdAndEntryAndToUserId(null, allinpaySettlementBO.getOrderId(), payEntry);
        if (Objects.nonNull(settlementPayInfo)) {
            logger.info("订单已在结算中，orderId={}", allinpaySettlementBO.getOrderId());
            throw new YamiShopBindException("订单已在结算中，请勿重复提交");
        }
        // 1.用户支付,目前暂时只有一条支付信息
        List<PayInfo> payInfoDbList = payInfoMapper.selectList(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo,allinpaySettlementBO.getPayId()));
        if (CollectionUtil.isEmpty(payInfoDbList)) {
            throw new YamiShopBindException("支付信息不存在");
        }
        // 1.用户退款
        List<RefundInfo> refundInfoDbList = refundInfoMapper.selectList(new LambdaQueryWrapper<RefundInfo>().eq(RefundInfo::getPayNo,allinpaySettlementBO.getPayId()));
        Map<String, List<RefundInfo>> refundInfoMap = refundInfoDbList.stream().collect(Collectors.groupingBy(RefundInfo::getPayNo));
        List<PayInfo> payInfoList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        SplitRuleVO shopSplitRuleDto = allinpaySettlementBO.getShopSplitRuleVO();
        // 分销金额
        List<SplitRuleVO> distributionUserSplitRuleList = allinpaySettlementBO.getDistributionUserSplitRuleList();
        SplitRuleVO platformSplitRuleDto = allinpaySettlementBO.getPlatformSplitRuleVO();
        setUserIdPrefix(shopSplitRuleDto, distributionUserSplitRuleList);
        long platformAmount = Objects.isNull(platformSplitRuleDto) ? 0L : platformSplitRuleDto.getFee();
        // 如果平台收入金额为负数，则需要转账给商家or分销员，此处考虑到商家还有一笔分账，优先转账给分销
        // 如果比平台需要转账的还大，就多转一份给商家/分销员，此时多转的部分再从商家分账里面扣除手续费给到平台
        // 平台转账
        if (platformAmount < 0L) {
            platformAmount = handlePlatformTransfer(shopSplitRuleDto, distributionUserSplitRuleList, platformAmount);
        }
        BatchAgentPay batchAgentPay = new BatchAgentPay();
        List<AgentPay> agentPayList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Allinpay allinpay = sysConfigService.getSysConfigObject(Constant.ALLINPAY_CONFIG, Allinpay.class);
        // 支付单号
        String payNo = String.valueOf(segmentService.getDateFormatSegmentId(SegmentIdKey.PAY));
        // 处理商家分账(平台分账，分销员分账)
        Long totalAmount = accountSharing(payInfoDbList, shopSplitRuleDto, distributionUserSplitRuleList, platformAmount,
                agentPayList, allinpay, refundInfoMap, payNo,payEntry);
        batchAgentPay.setTradeCode("4001");
        batchAgentPay.setBatchPayList(agentPayList);
        batchAgentPay.setBizBatchNo(allinpaySettlementBO.getOrderId());

        // 保存预支付信息
        PayInfo payInfo = new PayInfo();
        payInfo.setPayNo(payNo);
//        payInfo.setRefundId(0L);
        payInfo.setUserId(payInfoDbList.get(0).getUserId());
        payInfo.setPayAmount(Arith.toDecimalPrice(totalAmount).doubleValue());
        payInfo.setPayScore(0L);
        payInfo.setPayStatus(PayStatus.UNPAY.value());
        payInfo.setPayType(payInfoDbList.get(0).getPayType());
        payInfo.setVersion(0);
        payInfo.setOrderNumbers(allinpaySettlementBO.getOrderId());
        payInfo.setPayEntry(payEntry);
        payInfoMapper.insert(payInfo);
        boolean isSuccess = allinpayManager.batchShareAccountToShop(batchAgentPay);
        if(!isSuccess){
            throw new YamiShopBindException("结算失败");
        }
    }

    /**
     * 部分退款通联结算
     *
     * @param shopSplitRuleDto
     * @param orderNumber
     */
    public void doAllinPaySettlementByRefund(SplitRuleVO shopSplitRuleDto, String orderNumber) {
        Integer payEntry = PayEntry.ORDER_SETTLEMENT_BY_REFUND.value();
        // 找出当时支付的payId
        OrderSettlement orderSettlement = orderSettlementMapper.selectOne(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getOrderNumber, orderNumber).eq(OrderSettlement::getPayStatus, 1));
        PayInfo settlementPayInfo = payInfoMapper.getByOrderIdAndEntryAndToUserId(null, orderNumber, payEntry);
        if (Objects.nonNull(settlementPayInfo)) {
            logger.info("订单已在结算中，orderNumber={}", orderNumber);
            throw new YamiShopBindException("订单已在结算中，请勿重复提交");
        }
        // 1.用户支付
        List<PayInfo> payInfoDbList = payInfoMapper.selectList(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo,orderSettlement.getPayNo()));
        if (CollectionUtil.isEmpty(payInfoDbList)) {
            throw new YamiShopBindException("支付信息不存在");
        }
        // 1.用户退款
        List<RefundInfo> refundInfoDbList = refundInfoMapper.selectList(new LambdaQueryWrapper<RefundInfo>().eq(RefundInfo::getPayNo,orderSettlement.getPayNo()));
        Map<String, List<RefundInfo>> refundInfoMap = refundInfoDbList.stream().collect(Collectors.groupingBy(RefundInfo::getPayNo));

        List<PayInfo> payInfoList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        SplitRuleVO platformSplitRuleDto = new SplitRuleVO();
        platformSplitRuleDto.setFee(shopSplitRuleDto.getFee());
        setUserIdPrefix(shopSplitRuleDto, null);
        long platformAmount = Objects.isNull(platformSplitRuleDto) ? 0L : platformSplitRuleDto.getFee();
        // 如果平台收入金额为负数，则需要转账给商家or分销员，此处考虑到商家还有一笔分账，优先转账给分销
        // 如果比平台需要转账的还大，就多转一份给商家/分销员，此时多转的部分再从商家分账里面扣除手续费给到平台
        // 平台转账
        if (platformAmount < 0L) {
            platformAmount = handlePlatformTransfer(shopSplitRuleDto, null, platformAmount);
        }
        BatchAgentPay batchAgentPay = new BatchAgentPay();
        List<AgentPay> agentPayList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Allinpay allinpay = sysConfigService.getSysConfigObject(Constant.ALLINPAY_CONFIG, Allinpay.class);
        String payNo = String.valueOf(segmentService.getDateFormatSegmentId(SegmentIdKey.PAY));
        // 处理商家分账，平台分账
        long totalAmount = accountSharing(payInfoDbList, shopSplitRuleDto, null, platformAmount, agentPayList,
                allinpay, refundInfoMap, payNo,payEntry);
        batchAgentPay.setTradeCode("4001");
        batchAgentPay.setBatchPayList(agentPayList);
        batchAgentPay.setBizBatchNo(orderNumber);

        // 保存预支付信息
        PayInfo payInfo = new PayInfo();
        // 支付单号
        // 支付单号
        payInfo.setPayNo(payNo);
//        payInfo.setRefundId(0L);
        payInfo.setUserId(payInfoDbList.get(0).getUserId());
        payInfo.setPayAmount(Arith.toDecimalPrice(totalAmount).doubleValue());
        payInfo.setPayScore(0L);
        payInfo.setPayStatus(PayStatus.UNPAY.value());
        payInfo.setPayType(payInfoDbList.get(0).getPayType());
        payInfo.setVersion(0);
        payInfo.setOrderNumbers(orderNumber);
        payInfo.setPayEntry(payEntry);
        payInfoMapper.insert(payInfo);
        boolean isSuccess = allinpayManager.batchShareAccountToShop(batchAgentPay);
        if(!isSuccess){
            throw new YamiShopBindException("结算失败");
        }
    }

    /**
     * 通联结算，商家和分销员金额计算
     * @param orderChangeShopWalletAmountBO 订单
     * @param payNo 支付单号
     */
    public AllinpaySettlementBO getShopWaitSettlementAmount(OrderChangeShopWalletAmountBO orderChangeShopWalletAmountBO, String payNo) {
        String orderNumber = orderChangeShopWalletAmountBO.getOrderNumber();
        // 2.计算分销员所得
        List<SplitRuleVO> userSplitRuleList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        applicationContext.publishEvent(new GetDistributionUserIncomeEvent(orderNumber,userSplitRuleList));
        // 3.计算店铺所得
        List<ShopWalletLog> shopWalletLogs = shopWalletLogMapper.listByOrderNumber(orderNumber);
        // 商家&平台需要结算的钱
        ShopWalletLog payLog = null;

        ShopWalletLog shopRefundLog = new ShopWalletLog();
        shopRefundLog.setPlatformCommission(0.0);
        shopRefundLog.setUserAmount(0.0);
        shopRefundLog.setDistributionAmount(0.0);
        shopRefundLog.setPlatformCommission(0.0);
        shopRefundLog.setPlatformAmount(0.0);
        shopRefundLog.setChangeAomunt(0.0);
        shopRefundLog.setPlatformAmount(0.0);
        for (ShopWalletLog shopWalletLog : shopWalletLogs) {
            // 下单
            ShopWalletLog shopPayLog = null;
            shopRefundLog.setPaySysType(shopWalletLog.getPaySysType());
            if (Objects.equals(ShopWalletChangeReason.PAY.value(), shopWalletLog.getReason())) {
                shopPayLog =  shopWalletLog;
            }
            // 退款
            else if (Objects.equals(ShopWalletChangeReason.ORDER_REFUND.value(), shopWalletLog.getReason())) {
                shopRefundLog.setUserAmount(Arith.add(shopRefundLog.getUserAmount(), shopWalletLog.getUserAmount()));
                shopRefundLog.setDistributionAmount(Arith.add(shopRefundLog.getDistributionAmount(), shopWalletLog.getDistributionAmount()));
                shopRefundLog.setPlatformAmount(Arith.add(shopRefundLog.getPlatformAmount(), shopWalletLog.getPlatformAmount()));
                shopRefundLog.setPlatformCommission(Arith.add(shopRefundLog.getPlatformCommission(), shopWalletLog.getPlatformCommission()));
                // 如果因为退款收入，实际上是减少了退款的钱
                double changeAmount = (shopWalletLog.getIoType() == 1) ? -shopWalletLog.getChangeAomunt() : shopWalletLog.getChangeAomunt();
                shopRefundLog.setChangeAomunt(Arith.add(shopRefundLog.getChangeAomunt(), changeAmount));
            }
            // 退款超时，拒绝退款
            else if (Objects.equals(ShopWalletChangeReason.REJECT_REFUND.value(), shopWalletLog.getReason())) {
                //要把退款金额减去
                shopRefundLog.setUserAmount(Arith.sub(shopRefundLog.getUserAmount(), shopWalletLog.getUserAmount()));
                shopRefundLog.setDistributionAmount(Arith.sub(shopRefundLog.getDistributionAmount(), shopWalletLog.getDistributionAmount()));
                shopRefundLog.setPlatformAmount(Arith.sub(shopRefundLog.getPlatformAmount(), shopWalletLog.getPlatformAmount()));
                shopRefundLog.setPlatformCommission(Arith.sub(shopRefundLog.getPlatformCommission(), shopWalletLog.getPlatformCommission()));
                shopRefundLog.setChangeAomunt(Arith.sub(shopRefundLog.getChangeAomunt(), shopWalletLog.getChangeAomunt()));
            }
            if (shopPayLog != null) {
                payLog = shopPayLog;
            }
        }
        Double shopChangeAmount = Arith.sub((Objects.isNull(payLog) ? 0.0 : payLog.getChangeAomunt()), shopRefundLog.getChangeAomunt());
        SplitRuleVO shopSplitRuleVO = new SplitRuleVO();
        // 商家收入金额
        shopSplitRuleVO.setAmount(Arith.toLongCent(shopChangeAmount));
        // 平台收入金额
        if (Objects.isNull(payLog)) {
            shopSplitRuleVO.setFee(0L);
        } else {
            double platformAmount = Arith.sub(payLog.getPlatformAmount(), shopRefundLog.getPlatformAmount());
            double fee = Arith.sub(payLog.getPlatformCommission(), shopRefundLog.getPlatformCommission());
            shopSplitRuleVO.setFee(Arith.toLongCent(Arith.sub(fee, platformAmount)));
        }
        shopSplitRuleVO.setBizUserId(orderChangeShopWalletAmountBO.getShopId().toString());
        shopSplitRuleVO.setOrderNumber(orderNumber);

        AllinpaySettlementBO allinpaySettlementApiDto = new AllinpaySettlementBO();
        allinpaySettlementApiDto.setOrderId(orderNumber);
        allinpaySettlementApiDto.setPayId(payNo);
        allinpaySettlementApiDto.setShopSplitRuleVO(shopSplitRuleVO);
        allinpaySettlementApiDto.setDistributionUserSplitRuleList(userSplitRuleList);
        return allinpaySettlementApiDto;
    }


    /**
     * 处理下平台转账
     *
     * @param shopSplitRuleDto
     * @param distributionUserSplitRuleList
     * @param platformAmount
     * @return
     */
    private long handlePlatformTransfer(SplitRuleVO shopSplitRuleDto, List<SplitRuleVO> distributionUserSplitRuleList, long platformAmount) {

        platformAmount = Math.abs(platformAmount);
        // 平台需要转账的钱
        List<SplitRuleVO> splitRuleList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        // 1.优先转账给分销员
        if (CollectionUtil.isNotEmpty(distributionUserSplitRuleList)) {
            for (SplitRuleVO distributionSplitRuleVO : distributionUserSplitRuleList) {
                // 分销金额大于剩余要分帐的金额时处理下金额
                SplitRuleVO subSplitRuleVO = BeanUtil.map(distributionSplitRuleVO, SplitRuleVO.class);
                if (platformAmount > distributionSplitRuleVO.getAmount()) {
                    splitRuleList.add(subSplitRuleVO);

                    platformAmount = platformAmount - distributionSplitRuleVO.getAmount();
                    distributionSplitRuleVO.setAmount(0L);
                } else {
                    subSplitRuleVO.setAmount(platformAmount);
                    splitRuleList.add(subSplitRuleVO);

                    // 分销员这一步减少平台分账的金额，并进行下一步分账
                    distributionSplitRuleVO.setAmount(distributionSplitRuleVO.getAmount() - platformAmount);
                    platformAmount = 0;
                    break;
                }
                if (platformAmount <= 0) {
                    break;
                }
            }
        }
        // 如果小于0则表示平台多支出了一部分，因为这部分钱本来是由商家出的，将其设置为商家手续费转账给平台
        if (platformAmount < 0) {
            shopSplitRuleDto.setFee(Math.abs(platformAmount));
        }
        // 如果扣去分销员的钱后还有部分要转账的继续转账给商家
        if (platformAmount > 0) {
            // 此处商家收入金额 肯定大于 平台转账金额，因为用户支付了一笔，还需要结算的
            SplitRuleVO splitRuleVO = BeanUtil.map(shopSplitRuleDto, SplitRuleVO.class);
            splitRuleVO.setAmount(platformAmount);
            splitRuleList.add(splitRuleVO);

            // 最后要结算的金额减去平台转账的金额
            shopSplitRuleDto.setAmount(shopSplitRuleDto.getAmount() - platformAmount);
            platformAmount = 0;
        }
        // 执行平台转账
        for (SplitRuleVO splitRuleVO : splitRuleList) {
            splitRuleVO.setFee(0L);
            doPlatformTransfer(splitRuleVO);
        }
        return platformAmount;
    }

    /**
     * 平台转账
     * @param splitRuleVO
     */
    private void doPlatformTransfer(SplitRuleVO splitRuleVO) {
        PayInfo payInfo = payInfoMapper.getByOrderIdAndEntryAndToUserId(splitRuleVO.getBizUserId(), splitRuleVO.getOrderNumber(), PayEntry.PLATFORM_TRANSFER.value());
        if (Objects.nonNull(payInfo)) {
            return;
        }
        PayInfo platformPayInfo = new PayInfo();
        // 支付单号
        String payNo = String.valueOf(segmentService.getDateFormatSegmentId(SegmentIdKey.PAY));
        platformPayInfo.setPayNo(payNo);
//        platformPayInfo.setRefundId(0L);
        platformPayInfo.setUserId("0");
        platformPayInfo.setPayAmount(Arith.toDecimalPrice(splitRuleVO.getAmount()).doubleValue());
        platformPayInfo.setPayScore(0L);
        platformPayInfo.setPayStatus(PayStatus.PAYED.value());
//        platformPayInfo.setSysType(AuthUserContext.get().getSysType());
        platformPayInfo.setPayType(PayType.PLATFORM_BALANCE.value());
        platformPayInfo.setVersion(0);
        platformPayInfo.setToUserId(splitRuleVO.getBizUserId());
        // 保存多个支付订单号
        platformPayInfo.setOrderNumbers(splitRuleVO.getOrderNumber());
        platformPayInfo.setPayEntry(PayEntry.PLATFORM_TRANSFER.value());
        // 保存预支付信息
        payInfoMapper.insert(platformPayInfo);
        boolean flag = allinpayManager.execApplicationTransfer(payNo, splitRuleVO.getBizUserId(), Arith.toLongCent(platformPayInfo.getPayAmount()));
        if (!flag) {
            throw new YamiShopBindException(ResponseEnum.EXCEPTION);
        }
    }

    /**
     * 处理商家分账(平台分账，分销员分账)
     *
     * @param payInfoDbList
     * @param shopSplitRuleDto
     * @param distributionUserSplitRuleList
     * @param platformAmount
     * @param agentPayList
     * @param allinpay
     * @param refundInfoMap
     * @param payNo
     */
    private Long accountSharing(List<PayInfo> payInfoDbList, SplitRuleVO shopSplitRuleDto, List<SplitRuleVO> distributionUserSplitRuleList,
                                long platformAmount, List<AgentPay> agentPayList, Allinpay allinpay, Map<String, List<RefundInfo>> refundInfoMap, String payNo, Integer payEntry) {
        long totalPayAmount = 0L;
        for (PayInfo payInfo : payInfoDbList) {
            AgentPay agentPay = new AgentPay();
            List<RefundInfo> refundInfoList = refundInfoMap.get(payInfo.getPayNo());
            double refundAmount = 0.0;
            if(CollectionUtil.isNotEmpty(refundInfoList)) {
                // 计算退款金额总和
                for (RefundInfo refundInfoVO : refundInfoList) {
                    refundAmount = Arith.add(refundAmount, refundInfoVO.getRefundAmount());
                }
            }
            // 可分账金额
            long unSettlementPayAmount = Arith.toLongCent(Arith.sub(payInfo.getPayAmount(), refundAmount));
            long payAmount = unSettlementPayAmount;
            totalPayAmount = totalPayAmount + payAmount;
            // 1.先处理平台分账
            if (platformAmount > 0L) {
                // 如果平台分账金额大于当前可分账金额，则平台分账金额为当前可分账金额
                if (platformAmount > payAmount) {
                    agentPay.setFee(payAmount);
                    platformAmount = platformAmount - payAmount;
                } else {
                    agentPay.setFee(platformAmount);
                    platformAmount = 0L;
                }
                payAmount = payAmount - agentPay.getFee();
            }

            // 2.进行分销员分账
            if (CollectionUtil.isNotEmpty(distributionUserSplitRuleList) && payAmount > 0L) {
                List<SplitRule> splitRuleList = new ArrayList<>(Constant.INITIAL_CAPACITY);
                for (SplitRuleVO userSplitRuleVO : distributionUserSplitRuleList) {
                    // 分销员的手续费为0
                    userSplitRuleVO.setFee(0L);
                    if (userSplitRuleVO.getAmount() == 0L) {
                        continue;
                    }
                    // 如果分销员分账金额大于当前可分账金额，则分销员分账金额为当前可分账金额
                    if (payAmount > userSplitRuleVO.getAmount()) {
                        splitRuleList.add(BeanUtil.map(userSplitRuleVO, SplitRule.class));

                        payAmount -= userSplitRuleVO.getAmount();
                        userSplitRuleVO.setAmount(0L);
                    } else {
                        // 如果大于支付金额，则这次分摊给分销员的金额就是支付金额而不是分销员的分账金额
                        SplitRule partSplitRule = BeanUtil.map(userSplitRuleVO, SplitRule.class);
                        partSplitRule.setAmount(payAmount);
                        splitRuleList.add(partSplitRule);

                        // 减去支付金额下一轮继续进行分账
                        userSplitRuleVO.setAmount(userSplitRuleVO.getAmount() - payAmount);
                        payAmount = 0L;
                        break;
                    }
                    // 剩余可分账的金额如果为0，直接break
                    if (payAmount <= 0L) {
                        break;
                    }
                }
                agentPay.setSplitRuleList(splitRuleList);
            }
            agentPay.setAccountSetNo(allinpay != null ? allinpay.getAccountSetNo() : null);
            agentPay.setBizUserId(shopSplitRuleDto.getBizUserId());
            agentPay.setAmount(unSettlementPayAmount);
            agentPay.setFee(Objects.isNull(agentPay.getFee())? 0L : agentPay.getFee());
            agentPay.setTradeCode("4001");

            // 目前用户支付,目前只有一条支付信息,如果有多条,需要加特殊处理确保这里的bizOrderNo在通联那边唯一
            agentPay.setBizOrderNo(payNo);
            setCollectPayList(agentPay,payInfo.getPayNo(),payEntry);

            agentPayList.add(agentPay);
        }
        return totalPayAmount;
    }

    private void setCollectPayList(AgentPay agentPay, String payNo, Integer payEntry) {
        String domainName = shopConfig.getDomain().getApiDomainName();
        // 回调地址
        agentPay.setBackUrl(domainName + "/notice/pay/" + 1 + "/" + payEntry + "/" + 0);
        AgentPay.CollectPay collectPay = new AgentPay.CollectPay();
        collectPay.setAmount(agentPay.getAmount());
        collectPay.setBizOrderNo(payNo);
        agentPay.setCollectPayList(Collections.singletonList(collectPay));
    }

    private void setUserIdPrefix(SplitRuleVO shopSplitRuleDto, List<SplitRuleVO> distributionUserSplitRuleList) {
        if (Objects.nonNull(shopSplitRuleDto)) {
            shopSplitRuleDto.setBizUserId(AllinpayConstant.SHOP + shopSplitRuleDto.getBizUserId());
        }
        if (CollectionUtil.isNotEmpty(distributionUserSplitRuleList)) {
            for (SplitRuleVO splitRuleVO : distributionUserSplitRuleList) {
                splitRuleVO.setBizUserId(AllinpayConstant.USER + splitRuleVO.getBizUserId());
            }
        }
    }

}
